package com.cg.asm.body.controller.menu;

import com.alibaba.fastjson.JSONObject;
import com.cg.asm.body.config.loading.cache.menu.IMenuCache;
import com.cg.asm.body.domain.dto.menu.FunListRegDTO;
import com.cg.asm.body.domain.dto.menu.FunPointsDTO;
import com.cg.asm.body.domain.vo.menu.MenuListVO;
import com.cg.asm.body.domain.vo.menu.MenuPointsPagedVO;
import com.cg.asm.body.service.menu.IMenuService;
import com.cg.asm.body.util.AsmBodyCommonUtil;
import com.cg.asm.body.util.constants.DicEnum;
import com.cg.asm.body.util.constants.EnumGroup;
import com.cg.asm.client.CommonUtil;
import com.cg.asm.client.domain.user.UserInfo;
import com.cg.asm.client.exception.MybatisExample;
import com.github.pagehelper.PageInfo;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiImplicitParam;
import io.swagger.annotations.ApiImplicitParams;
import io.swagger.annotations.ApiOperation;
import org.springframework.beans.propertyeditors.CustomDateEditor;
import org.springframework.web.bind.WebDataBinder;
import org.springframework.web.bind.annotation.*;

import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;

@Api(tags = "MenuController", value = "功能清单接口")
@RestController
@RequestMapping("/menu")
public class MenuController {

    private IMenuService menuService;
    private IMenuCache menuCache;

    public MenuController(IMenuService menuService, IMenuCache menuCache) {
        this.menuService = menuService;
        this.menuCache = menuCache;
    }

    @InitBinder
    public void intDate(WebDataBinder dataBinder) {
        SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
        dateFormat.setLenient(false);
        dataBinder.registerCustomEditor(Date.class, new CustomDateEditor(dateFormat, true));
    }

    @ApiOperation(value = "获取功能清单树信息", notes = "使用场景：功能清单主页面")
    @GetMapping("/menuTreeData")
    public JSONObject menuTreeData() {
        UserInfo userLoginVO = AsmBodyCommonUtil.getCurrentUserLoginVO();
        List<MenuListVO> cacheMenuTreeData = new ArrayList<>();
        if (null != userLoginVO && "super".equals(userLoginVO.getUserId())) {
            cacheMenuTreeData = menuCache.getCacheMenuTreeData();
        }
        return CommonUtil.successJson(cacheMenuTreeData);
    }

    @ApiOperation(value = "获取功能清单功能点列表信息", notes = "功能点")
    @ApiImplicitParams({
            @ApiImplicitParam(name = "pageIndex", value = "当前页码", required = true, dataType = "String", paramType = "query"),
            @ApiImplicitParam(name = "pageSize", value = "分页尺寸", required = true, dataType = "String", paramType = "query"),
            @ApiImplicitParam(name = "sortBy", value = "排序项", dataType = "String", paramType = "query"),
            @ApiImplicitParam(name = "descending", value = "正序/倒序", dataType = "boolean", paramType = "query"),
            @ApiImplicitParam(name = "filter", value = "过滤条件", dataType = "String", paramType = "query")
    })
    @GetMapping("/funPointsPagedList")
    public JSONObject funPointsPagedList(String pageIndex, String pageSize, String sortBy, boolean descending, String filter) {
        PageInfo<MenuPointsPagedVO> contentsPaginator = menuService.funPointsPagedList(MybatisExample.initPagedInfo(
                pageIndex,
                pageSize,
                sortBy,
                descending,
                filter
        ));
        return CommonUtil.successJson(contentsPaginator);
    }

    @ApiOperation(value = "获取功能点默认选中数据集", notes = "功能点")
    @GetMapping("/defaultSelectOptions")
    public JSONObject defaultSelectOptions() {
        return CommonUtil.successJson(DicEnum.getEnum(EnumGroup.SF));
    }

    @ApiOperation(value = "获取功能清单类别数据集", notes = "功能清单")
    @GetMapping("/funListTypeOptions")
    public JSONObject funListTypeOptions() {
        return CommonUtil.successJson(DicEnum.getEnum(EnumGroup.FUN_LIST_TYPE));
    }

    @ApiOperation(value = "保存菜单信息", notes = "功能清单")
    @ApiImplicitParams({
            @ApiImplicitParam(name = "funListRegDTO", value = "功能清单注册对象", required = true, dataType = "FunListRegDTO", paramType = "body")
    })
    @PostMapping("/saveMenu")
    public JSONObject saveMenu(FunListRegDTO funListRegDTO) {
        try {
            menuService.saveMenuRoot(funListRegDTO);
            menuCache.initMenuPointsAndRole();
            return CommonUtil.successJson();
        } catch (Exception e) {
            e.printStackTrace();
            return CommonUtil.errorJson();
        }
    }

    @ApiOperation(value = "删除功能清单", notes = "功能清单")
    @ApiImplicitParams({
            @ApiImplicitParam(name = "funListCode", value = "功能清单编码", required = true, dataType = "String", paramType = "body")
    })
    @DeleteMapping("/delMenu")
    public JSONObject delMenu(@RequestBody String funListCode) {
        try {
            menuService.delMenu(funListCode);
            menuCache.initMenuPointsAndRole();
            return CommonUtil.successJson();
        } catch (Exception e) {
            e.printStackTrace();
            return CommonUtil.errorJson();
        }
    }

    @ApiOperation(value = "根据菜单编码，查询菜单详细信息", notes = "功能清单")
    @ApiImplicitParams({
            @ApiImplicitParam(name = "funListCode", value = "功能清单编码", required = true, dataType = "String", paramType = "path")
    })
    @GetMapping("/editMenuFrom/{funListCode}")
    public JSONObject editMenuFrom(@PathVariable String funListCode) {
        MenuListVO menuListVO = menuService.getMenuByCode(funListCode);
        return CommonUtil.successJson(menuListVO);
    }

    @ApiOperation(value = "保存编辑菜单信息", notes = "功能清单")
    @ApiImplicitParams({
            @ApiImplicitParam(name = "funListRegDTO", value = "功能清单注册对象", required = true, dataType = "FunListRegDTO", paramType = "body")
    })
    @PutMapping("/saveEditMenu")
    public JSONObject saveEditMenu(FunListRegDTO funListRegDTO) {
        try {
            menuService.saveEditMenu(funListRegDTO);
            menuCache.initMenuPointsAndRole();
            return CommonUtil.successJson();
        } catch (Exception e) {
            e.printStackTrace();
            return CommonUtil.errorJson();
        }
    }

    @ApiOperation(value = "验证功能点编码是否唯一", notes = "功能点")
    @ApiImplicitParams({
            @ApiImplicitParam(name = "funPointsCode", value = "功能点编码", required = true, dataType = "String", paramType = "path")
    })
    @GetMapping("/funPointsCodeIsUnique/{funPointsCode}")
    public JSONObject funPointsCodeIsUnique(@PathVariable String funPointsCode) {
        boolean unique = menuService.funPointsCodeIsUnique(funPointsCode);
        return CommonUtil.successJson(unique);
    }

    @ApiOperation(value = "保存功能点信息", notes = "功能点")
    @ApiImplicitParams({
            @ApiImplicitParam(name = "funPointsDTO", value = "功能点对象", required = true, dataType = "funPointsDTO", paramType = "body")
    })
    @PostMapping("/saveFunPoints")
    public JSONObject saveFunPoints(FunPointsDTO funPointsDTO) {
        try {
            menuService.saveFunPoints(funPointsDTO);
            menuCache.initMenuPointsAndRole();
            return CommonUtil.successJson();
        } catch (Exception e) {
            e.printStackTrace();
            return CommonUtil.errorJson();
        }
    }

    @ApiOperation(value = "根据功能点编码删除功能点", notes = "功能点")
    @ApiImplicitParams({
            @ApiImplicitParam(name = "funPointsCode", value = "功能点编码", required = true, dataType = "String", paramType = "body")
    })
    @DeleteMapping("/delPoints")
    public JSONObject delPoints(@RequestBody String funPointsCode) {
        try {
            menuService.delPoints(funPointsCode);
            menuCache.initMenuPointsAndRole();
            return CommonUtil.successJson();
        } catch (Exception e) {
            e.printStackTrace();
            return CommonUtil.errorJson();
        }
    }

    @ApiOperation(value = "更新功能点信息", notes = "功能点")
    @ApiImplicitParams({
            @ApiImplicitParam(name = "funPointsDTO", value = "功能点对象", required = true, dataType = "funPointsDTO", paramType = "body")
    })
    @PostMapping("/saveEditPoints")
    public JSONObject saveEditPoints(FunPointsDTO funPointsDTO) {
        try {
            menuService.saveEditPoints(funPointsDTO);
            menuCache.initMenuPointsAndRole();
            return CommonUtil.successJson();
        } catch (Exception e) {
            e.printStackTrace();
            return CommonUtil.errorJson();
        }
    }
}
